package top.ucat.x.system.service.management;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.ucat.box.starter.mybatis.plus.base.service.BaseCrudServiceImpl;
import top.ucat.x.system.dao.api.SysMenuDao;
import top.ucat.x.system.dao.api.SysUserDao;
import top.ucat.x.system.entity.SysMenu;
import top.ucat.x.system.entity.SysRolePermission;
import top.ucat.x.system.entity.SysUser;
import top.ucat.x.system.entity.beans.menu.MenuTreeVo;
import top.ucat.x.system.utils.MenuUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Auther: Jun
 * @Date: 2020/4/20 15:41
 * @Description:
 */
@Service
@Slf4j
public class SysMenuServiceImpl extends BaseCrudServiceImpl<SysMenu> implements SysMenuService {

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysMenuDao sysMenuDao;

    @Autowired
    private SysRolePermissionService sysRolePermissionService;


    @Override
    public List<SysMenu> getAllMenu() {
        LambdaQueryWrapper<SysMenu> wrapper = sysMenuDao.getWrapper().lambda().orderByAsc(SysMenu::getSort);
        List<SysMenu> list = sysMenuDao.list(wrapper);
        return list;
    }

    @Override
    public List<MenuTreeVo> getAllMenuTrees() {
        List<SysMenu> allMenus = getAllMenu();
        List<MenuTreeVo> menuTrees = this.getMenuTree(allMenus);
        return menuTrees;
    }

    @Override
    public List<MenuTreeVo> getTopMenuTrees(String userId) {

        log.debug("获取用户顶级菜单");
        SysUser userInfo = sysUserService.queryById(userId);
        log.debug("用户信息:[{}]", userInfo.toString());
        List<SysMenu> menuList = this.getUserPermissionMenus(userId);
        List<MenuTreeVo> treeList = menuList.stream()
                .filter(m -> StringUtils.isBlank(m.getParentId()))
                .map(sysmenu -> MenuUtil.getMenuTreeVoBySysMenu(sysmenu))
                .collect(Collectors.toList());
        return treeList;
    }

    @Override
    public List<MenuTreeVo> getUserMenuTree(String userId) {
        List<SysMenu> menus = this.getUserPermissionMenus(userId);
        List<MenuTreeVo> menuTrees = this.getMenuTree(menus);
        return menuTrees;
    }

    @Override
    public List<MenuTreeVo> getUserMenuTrees(String userId, String menuParentId) {

        //获取用的菜单树
        List<MenuTreeVo> menuTrees = this.getUserMenuTree(userId);

        //当没有parentId的时候默认返回第一项顶级菜单下的菜单
        if (StringUtils.isEmpty(menuParentId)) {
            List<MenuTreeVo> topMenu = this.getTopMenuTrees(userId);
            if (topMenu != null && topMenu.size() > 0) {
                MenuTreeVo menuTreeVo = topMenu.get(0);
                menuParentId = menuTreeVo.getId();
            }
        }
        if (!menuTrees.isEmpty()) {
            String finalParentId = menuParentId;
            MenuTreeVo menuTreeVo = menuTrees.stream().filter(treeVo -> treeVo.getId().equals(finalParentId)).findFirst().get();
            return menuTreeVo.getChildren();
        }
        return new ArrayList<>();
    }


    @Override
    public List<SysMenu> getUserPermissionMenus(String userId) {
        log.debug("获取用户id:[{}]", userId);
        SysUser userInfo = sysUserService.queryById(userId);
        log.debug("用户信息:[{}]", userInfo.toString());
        List<SysMenu> menuList = null;
        if (userInfo.isAdmin()) {
            log.debug("用户是管理员身份,获取全部的菜单");
            menuList = this.getAllMenu();
        } else {
            log.debug("用户不是管理员身份,获取权限内的菜单");
            QueryWrapper<SysMenu> wrapper = sysMenuDao.getWrapper()
                    .orderByAsc("sort");
            List<String> menuIds = this.getUserPermissionMenuIds(userId);
            if (menuIds == null || (menuIds != null && menuIds.isEmpty())) {
                return new ArrayList<>();
            }
            log.debug("菜单id:[{}]", menuIds);
            wrapper.in("id", menuIds);
            menuList = sysMenuDao.list(wrapper);
        }
        if (!(menuList != null && menuList.size() > 0)) {
            return new ArrayList<>();
        }
        return menuList;
    }

    @Override
    public List<String> getUserPermissionMenuIds(String userId) {
        List<SysRolePermission> permissions = sysRolePermissionService.getUserPermission(userId);
        List<String> menuIds = permissions.stream()
                //查看权限
                .filter(p -> p.getType() == 4)
                .map(SysRolePermission::getMenuId).collect(Collectors.toList());
        return menuIds;
    }


    private List<MenuTreeVo> getMenuTree(List<SysMenu> menus) {
        //原始菜单
        List<MenuTreeVo> rootMenus = menus.stream().map(m -> MenuUtil.getMenuTreeVoBySysMenu(m)).collect(Collectors.toList());
        //整合顶级菜单
        List<MenuTreeVo> topMenus = rootMenus.stream()
                //没有父级id为顶级菜单
                .filter(m -> StringUtils.isEmpty(m.getParentId()))
                .map(menu -> {
                    //填充子菜单
                    menu.setChildren(getChildMenuTrees(menu.getId(), rootMenus));
                    return menu;
                }).collect(Collectors.toList());
        return topMenus;
    }

    private List<MenuTreeVo> getChildMenuTrees(String parentId, List<MenuTreeVo> rootMenus) {
        List<MenuTreeVo> childMenuTree = rootMenus.stream()
                //排除顶级菜单
                .filter(m -> StringUtils.isNotBlank(m.getParentId()) && m.getParentId().equals(parentId))
                .map(menu -> {
                    menu.setChildren(getChildMenuTrees(menu.getId(), rootMenus));
                    return menu;
                }).collect(Collectors.toList());
        return childMenuTree;
    }

}
